package io.geekidea.boot.allocation.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.geekidea.boot.allocation.dto.AllocationExcel;
import io.geekidea.boot.allocation.dto.addAllocation;
import io.geekidea.boot.allocation.dto.addWL;
import io.geekidea.boot.allocation.entity.Allocation;
import io.geekidea.boot.allocation.query.AllocationQuery;
import io.geekidea.boot.allocation.query.MaterialQuery;
import io.geekidea.boot.allocation.sevice.AllocationService;
import io.geekidea.boot.auth.util.LoginUtil;
import io.geekidea.boot.common.PageDto;
import io.geekidea.boot.framework.response.ApiResult;
import io.geekidea.boot.materials.entity.Materials;
import io.geekidea.boot.materials.mapper.MaterialsMapper;
import io.geekidea.boot.materials.service.MaterialsService;
import io.geekidea.boot.otherstores.entity.OtherStores;
import io.geekidea.boot.otherstores.query.total;
import io.geekidea.boot.store.entity.OneStore;
import io.geekidea.boot.store.service.StoreService;
import io.geekidea.boot.system.dto.SysUserExcel;
import io.geekidea.boot.system.entity.SysUser;
import io.geekidea.boot.system.query.SysUserQuery;
import io.geekidea.boot.system.service.SysUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/allocation")
@Tag(name = "调拨单")
public class allocationController {
    @Resource
    private AllocationService allocationService;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private StoreService storeService;
    @Resource
    private MaterialsService materialsService;
    @Resource
    private MaterialsMapper materialsMapper;


    @PostMapping("/getList")
    public ApiResult List(@RequestBody  AllocationQuery allocationQuery){
        List<Allocation> list = allocationService.getList(allocationQuery);
        long total = allocationService.getTotal(allocationQuery).getTotal();
        PageDto<Allocation> pageDto = new PageDto<>(list,total,allocationQuery.getPageSize(),allocationQuery.getPageIndex()+1);
        return ApiResult.success(pageDto);
    }

    @PostMapping("/getWlList")
    public ApiResult getWLList(@RequestBody MaterialQuery materialQuery){

        LambdaQueryWrapper<Materials> list = new LambdaQueryWrapper<>();
        list.eq(Materials::getStoresId,materialQuery.getStoresId());


        List<Materials> materials = materialsMapper.selectList(list);

        return ApiResult.success(materials);
    }

    @PostMapping("/getWL")
    public ApiResult getWL(@RequestBody MaterialQuery materialQuery){
        List<Materials> wl = allocationService.getWL(materialQuery);
        return ApiResult.success(wl);
    }



    @PostMapping("/addAllocation")
    public ApiResult add( @RequestBody addAllocation addAllocation) throws Exception {
        System.out.println(addAllocation);
        addAllocation.setCreatorUser(LoginUtil.getUserId());

        Integer storesOutId = addAllocation.getStoresOutId();
        OneStore oneStore = storeService.getOneStore(storesOutId);
        String code = oneStore.getCode();
        String str = generateOrderNumber(code);

        addAllocation.setTransferNum(str);


        boolean b = allocationService.addAllocation(addAllocation);
        if (!b) {
            return ApiResult.success("添加失败",b);
        }
        List<Materials> collect = addAllocation.getAddWLList().stream().map(time -> {
            Materials byId = materialsService.getById(time.getMaterialId());
            byId.setAvailableInventory(String.valueOf(Integer.valueOf(byId.getAvailableInventory()) - time.getTotalInventory()));
            byId.setTotalStock((int) (Integer.valueOf(byId.getTotalStock()) - time.getTotalInventory()));
            materialsService.updateById(byId);
            byId.setAvailableInventory(time.getTotalInventory().toString());
            byId.setNumbers(str);
            byId.setMaterialsource("调拨");
            byId.setTotalStock(Integer.valueOf(time.getTotalInventory().toString()));
            byId.setStockage(1);
            byId.setAreaId(addAllocation.getAreaInId());
            byId.setStoresId(addAllocation.getStoresInId());
            byId.setInOrderNumber(time.getNumbers());
            byId.setCreatedTime(LocalDateTime.now());
            byId.setId(null);
            try {
                byId.setCreatedBy(LoginUtil.getUsername());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return byId;
        }).collect(Collectors.toList());
        materialsService.saveBatch(collect);
        return ApiResult.success("添加成功",b);


    }

    @PostMapping("/yanshou/{id}")
    public ApiResult yanshou(@PathVariable Long id) throws Exception {

        Allocation allocation = new Allocation();

        UpdateWrapper<Allocation> wrapper = new UpdateWrapper<>();

        wrapper.eq("id",id)
                .set("status","2")
                .set("completeTime", LocalDate.now())
                .set("checkUser",LoginUtil.getUserId());

        allocationService.update(null,wrapper);
        return ApiResult.success("验收成功");
    }


    @PostMapping("/del/{id}")
    public ApiResult deleted(@PathVariable Long id) throws Exception {

        Allocation byId = allocationService.getById(id);

        String transferNum = byId.getTransferNum();
        QueryWrapper<Materials> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("numbers", transferNum);
        List<Materials> materials = materialsMapper.selectList(queryWrapper);


        //找到调拨单物料
        for (Materials material : materials) {
            //找到对应的入库物料
            LambdaQueryWrapper<Materials> RK =new LambdaQueryWrapper<>();
                  RK.eq(StringUtils.isNotBlank(material.getInOrderNumber()),Materials::getNumbers,material.getInOrderNumber())
                    .eq(StringUtils.isNotBlank(material.getCode()),Materials::getCode,material.getCode())
                    .eq(StringUtils.isNotBlank(material.getTaxsh()),Materials::getTaxsh,material.getTaxsh());

            Materials one = materialsMapper.selectOne(RK);
            one.setAvailableInventory(String.valueOf(Integer.valueOf( material.getAvailableInventory())  + Integer.valueOf(one.getAvailableInventory())));
           // one.setTotalStock(material.getTotalStock()+one.getTotalStock());
            materialsMapper.updateById(one);

            UpdateWrapper<Materials> wrapper = new UpdateWrapper<>();
            wrapper.eq("id",material.getId())
                    .set("deleted","1");
            materialsService.update(null, wrapper);
        }
        UpdateWrapper<Allocation> wrapper = new UpdateWrapper<>();

        wrapper.eq("id",id)
                .set("deleted","1");

        boolean update = allocationService.update(null, wrapper);
        if (!update) {
            return ApiResult.success("取消失败，请和管理员沟通");
        }
        return ApiResult.success("取消成功，感谢使用");
    }


    @PostMapping("/getUserList")
    public ApiResult getUserList(){
        List<SysUser> list = sysUserService.list();
        List<Map<String, Object>> userList = new ArrayList<>();
        for (SysUser user : list) {
            String name = user.getUsername();
            long id = user.getId();
            Map<String, Object> userMap = new HashMap<>();
            userMap.put("name", name);
            userMap.put("id", id);
            userList.add(userMap);
        }
        return ApiResult.success(userList);
    }

    @PostMapping("/getAllocationById/{id}")
    public ApiResult getAllocationById(@PathVariable Integer id){
        Allocation byId = allocationService.getById(id);
        return ApiResult.success(byId);
    }

    @PostMapping("/getMaterialsByNumber/{number}")
    public ApiResult getMaterialsByNumber(@PathVariable String number){
        LambdaQueryWrapper<Materials> materials =new LambdaQueryWrapper<>();
        materials.eq(StringUtils.isNotBlank(number),Materials::getNumbers,number );

        List<Materials> materials1 = materialsMapper.selectList(materials);

        return ApiResult.success(materials1);
    }

    @PostMapping("/export")
    @Operation(tags = "Post",description = "导出")
    public void download(@RequestBody AllocationQuery allocationQuery, HttpServletResponse response){
        //WarehousentryQuery warehousentryQuery = new WarehousentryQuery();

        List<AllocationExcel> list = allocationService.getListExcel(allocationQuery);
        OutputStream outputStream = null;
        try {
            response.setCharacterEncoding("UTF-8");
            String excelName = URLEncoder.encode("调拨单"+ LocalDateTime.now(), "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + excelName + ".xlsx");
            // 以字节流的形式输出响应正文
            outputStream = response.getOutputStream();
            try (ExcelWriter excelWriter = EasyExcel.write(outputStream, AllocationExcel.class).build()) {
                WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
                excelWriter.write(list,writeSheet);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    }




    //根据门店编号生成入库单号
    public String generateOrderNumber(String storeCode) {
        LocalDateTime now = LocalDateTime.now();
        String formattedDate = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        long sequenceNumber = new Date().getTime();
        return "db_" + storeCode + "_" + formattedDate + "_" + sequenceNumber;
    }




}
